﻿namespace NTLib.Pipe
{
    using NTLib.Pipe.Descriptors;
    using NTLib.Pipe.Targets;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Pipe's source interface use to exchange data through everything.
    /// </summary>
    public interface IPipeSource : IPipe
    {
        #region Properties

        /// <summary>
        /// Gets the value indicating that the current pipe allow the user to pop items through it.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance can pop item; otherwise, <c>false</c>.
        /// </value>
        bool CanPopItem { get; }

        /// <summary>
        /// Gets the value indicating that the current pipe allow the user to push items through it.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance can push item; otherwise, <c>false</c>.
        /// </value>
        bool CanPushItem { get; }

        /// <summary>
        /// Gets the other side target information.
        /// </summary>
        /// <remarks>The target null define that the pipe is not attach yet.</remarks>
        ITargetDescriptor Target { get; }

        #endregion

        #region Event

        /// <summary>
        /// Occurs when the item disposed.
        /// </summary>
        event Action<object> ItemDisposed;

        #endregion

        #region methods

        /// <summary>
        /// Initializes the current pipe asynchronously.
        /// </summary>
        /// <returns>Task used to make this initialization asynchronously.</returns>
        Task InitializeAsync(ITargetDescriptor desc, PipeType type, CancellationToken token = default(CancellationToken));

        #endregion
    }

    /// <summary>
    /// Pipe interface use to exchange data through everything.
    /// </summary>
    /// <typeparam name="T">Type item that will navigate through.</typeparam>
    public interface IPipeSource<T> : IPipeSource
    {
        #region Event

        /// <summary>
        /// Occurs when some data have been received on the pipe.
        /// </summary>
        event Action DataReceived;

        #endregion

        #region Methods

        /// <summary>
        /// Called when the update pop waiter is called.
        /// This methods is used to dequeue item from the queue to the waiter.
        /// The call is thread safe.
        /// </summary>
        Task<T> DequeueItemAsync(CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Pushes the item on the storage system without waiting any response.
        /// The call is thread safe.
        /// </summary>
        Task SendItemAsync(T item, CancellationToken token = default(CancellationToken));

        #endregion
    }
}
